<script setup>
import { generateTable, generateMultipleTable } from '@/utils/js2table.js'
import html2canvas from 'html2canvas'
import printJS from 'print-js'
import { ref, watchEffect } from 'vue'
import { runApi } from '../apiConfig/index'

defineOptions({
    inheritAttrs: false,
    name: 'Ticket'
})

const props = defineProps({
    config: {
        type: [Object, Array],
        default: () => { }
    },
    noprint: {
        type: Boolean,
        default: false
    },
    apiParams: Object,
    apiHeader: Object,
    type: String,
    apiProxy: {
        type: String,
        default: '/api'
    }
});


const ticketRef = ref(null)
const isPrinting = ref(false)
const printParams = ref({
    pageSize: 'A4',
    orientation: 'portrait',
    printType: 'html' // 'html'或'image'
})


const handlePrint = async () => {
    const { pageSize, orientation, printType } = printParams.value
    try {
        isPrinting.value = true
        const element = ticketRef.value

        if (printType === 'html') {
            // 设置打印样式
            const printStyle = `
            @page {
                size: ${pageSize} ${orientation};
            }
            @media print {
                body {
                    margin: 0;
                    padding: 0;
                }
                * {
                    max-width: 100% !important;
                    page-break-inside: avoid;
                }
                .cs-print {
                    width: 100%;
                    min-height: 100%;
                    padding: 4px;
                    margin: unset;
                }
                .cs-print > * {
                    margin: 0 !important;
                }
            }`

            printJS({
                printable: element,
                type: 'html',
                style: printStyle,
                scanStyles: true,
                targetStyles: ['*'],
            })
        } else {

            const printStyle1 = `
            @page {
                size: ${pageSize} ${orientation};
                margin: 0;
            }
            @media print {
                body {
                    margin: 0;
                    padding: 0;
                }
                img {
                    max-width: 100% !important;
                    height: auto !important;
                    page-break-inside: avoid;
                    position: relative;
                    top: 0;
                }
                .cs-print {
                    width: fit-content;
                    min-height: 100%;
                }
                table {
                    border-collapse: collapse;
                    table-layout: fixed;
                }
                
            }`

            // 图片打印方式
            const isLandscape = orientation === 'landscape'
            const scale = pageSize === 'A3' ? 1.8 : 2

            const canvas = await html2canvas(element, {
                scale,
                useCORS: true,
                allowTaint: true,
                logging: false,
                backgroundColor: null,
            })

            const dataUrl = canvas.toDataURL('image/png')

            printJS({
                printable: dataUrl,
                type: 'image',
                style: printStyle1,
                scanStyles: true
            })
        }
    } catch (error) {
        console.error('打印失败:', error)
    } finally {
        isPrinting.value = false
    }
}

watchEffect(async () => {
    if (!props.config) return

    let cdata = props.config

    try {
        if (props.apiParams && props.type) {
            cdata = await runApi(props.config, props.type, props.apiParams, { baseURL: props.apiProxy, ...props.apiHeader })
        }
    } catch (error) {
        cdata = props.config
        console.log('api请求失败，将以默认配置展示表单')
    } finally {
        if (!cdata) cdata = props.config

        let tableEle
        if (Array.isArray(cdata)) {
            tableEle = generateMultipleTable(cdata)
        } else {
            tableEle = generateTable(cdata)
        }

        if (ticketRef.value) {
            ticketRef.value.innerHTML = ''
            ticketRef.value.appendChild(tableEle)
        }
    }

})


</script>

<template>

    <div class="h-full w-fit m-auto">

        <div class="cs-print" ref="ticketRef" v-bind="$attrs"> </div>

        <div class="absolute right-[20px] top-[20px] flex items-center gap-2" v-if="!noprint">
            <select v-model="printParams.pageSize"
                class="border border-gray-300 rounded px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-blue-500">
                <option value="A4">A4</option>
                <option value="A3">A3</option>
            </select>

            <select v-model="printParams.orientation"
                class="border border-gray-300 rounded px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-blue-500">
                <option value="portrait">纵向</option>
                <option value="landscape">横向</option>
            </select>

            <select v-model="printParams.printType"
                class="border border-gray-300 rounded px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-blue-500">
                <option value="html">HTML打印</option>
                <option value="image">图片打印</option>
            </select>

            <div class="border border-blue-700 rounded-[50%] w-[32px] h-[32px] text-xs flex justify-center items-center font-bold cursor-pointer shadow hover:bg-blue-50 active:bg-blue-100 transition-colors"
                @click="handlePrint(printParams.pageSize, printParams.orientation)" :disabled="isPrinting">
                <span v-if="!isPrinting">打印</span>
                <svg v-else class="animate-spin h-4 w-4 text-blue-700" xmlns="http://www.w3.org/2000/svg" fill="none"
                    viewBox="0 0 24 24">
                    <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
                    <path class="opacity-75" fill="currentColor"
                        d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z">
                    </path>
                </svg>
            </div>
        </div>
    </div>
</template>

<style>
.cs-print {
    width: fit-content;
    min-height: 100%;
    padding: 4px;
}
</style>